import type { RouteRecordRaw } from 'vue-router';
import type { App } from 'vue';
import { TITLE } from '/@/setting';
import { createRouter, createWebHashHistory } from 'vue-router';
import { basicRoutes } from './basicRoutes';
import NProgress from 'nprogress'; // progress bar
import 'nprogress/nprogress.css'; // progress bar style
import { getTokenCache } from '/@/utils/auth'; // getToken from cookie
import { useUserStoreWithOut } from '/@/store/modules/user';
import { usePermissionStoreWithOut } from '/@/store/modules/permission';

NProgress.configure({ showSpinner: false }); // NProgress Configuration
const whiteList = ['/login']; // no redirect whitelist

// app router
export const router = createRouter({
  history: createWebHashHistory(),
  routes: basicRoutes as unknown as RouteRecordRaw[],
  strict: true,
  scrollBehavior: () => ({ left: 0, top: 0 }),
});

const userStore = useUserStoreWithOut();
const permissionStore = usePermissionStoreWithOut();

router.beforeEach((to, _from, next) => {
  if (to.meta.title) {
    document.title = to.meta.title + ' - ' + TITLE;
  }
  NProgress.start();
  if (getTokenCache()) {
    // 已登录且要跳转的页面是登录页
    if (to.path === '/login') {
      next({ path: '/' });
      NProgress.done();
    } else {
      if (userStore.getRoles?.length === 0) {
        // 判断当前用户是否已拉取完user_info信息
        loadUserInfo(next, to);
        // 登录时未拉取 菜单，在此处拉取
      } else if (userStore.getLoadMenus) {
        // 修改成false，防止死循环
        userStore.updateLoadMenusAction();
        permissionStore.LoadMenusAction(next, to);
      } else {
        next();
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) {
      // 在免登录白名单，直接进入
      next();
    } else {
      next(`/login?redirect=${to.fullPath}`); // 否则全部重定向到登录页
      NProgress.done();
    }
  }
});

export const loadUserInfo = async (next, to) => {
  try {
    await userStore.UserInfoAction();
    // 拉取user_info,动态路由，拉取菜单
    await permissionStore.LoadMenusAction(next, to);
  } catch (error) {
    userStore.LogOutAction();
  }
};

router.afterEach(() => {
  NProgress.done(); // finish progress bar
});

// config router
export function setupRouter(app: App<Element>) {
  app.use(router);
}
